import { Table } from "./interface";
import { reactive, computed, onMounted, toRefs } from "vue";

/**
 * @description table 页面操作方法封装
 * @param {Function} api 获取表格数据 api 方法(必传)
 * @param {Object} initParam 获取数据初始化参数(非必传，默认为{})
 * @param {Boolean} isPageable 是否有分页(非必传，默认为true)
 * @param {Function} dataCallBack 对后台返回的数据进行处理的方法(非必传)
 * */
export function getPageSize({ rowHeight = 45, offsetHeight = 15 }: { rowHeight?: number; offsetHeight?: number }) {
	let bodyHeight = document.body.clientHeight;
	let headerHeight = document.querySelector("#app .el-header")?.clientHeight || 54;
	let breadcrumbHeight = document.querySelector("#app .breadcrumb-box")?.clientHeight || 39;
	let searchHeight = document.querySelector("#app .el-main .card.table-search")?.clientHeight || 76;
	let height =
		bodyHeight -
		(headerHeight + 1) - //顶部菜单
		(breadcrumbHeight + 1) - //面包屑
		searchHeight - //表格搜索框
		rowHeight - //表头
		(47 + 20) - //表格标题按钮栏+列表padding
		(52 + 20) - //分页栏+列表padding
		offsetHeight - //offset
		30; //main padding
	return parseInt((height / rowHeight).toFixed(0));
}
export const useTable = (
	api: (params: any) => Promise<any>,
	selectId: any,
	initParam: any,
	isPageable: boolean = true,
	ignoreInit: boolean = false,
	dataCallBack?: (data: any) => any
) => {
	const state = reactive<Table.TableStateProps>({
		defaultExpandKeys: [],
		// 表格数据
		tableData: [],
		// 分页数据
		pageable: {
			// 当前页数
			pageIndex: 1,
			// 每页显示条数
			pageSize: getPageSize({}),
			// 总条数
			total: 0,
			pageSizes: [10, 20, 50, 100, 500]
		},
		// 查询参数(只包括查询)
		searchParam: {},
		// 初始化默认的查询参数
		searchInitParam: {},
		// 总参数(包含分页和查询参数)
		totalParam: {}
	});

	/**
	 * @description 分页查询参数(只包括分页和表格字段排序,其他排序方式可自行配置)
	 * */
	const pageParam = computed({
		get: () => {
			return {
				pageIndex: state.pageable.pageIndex,
				pageSize: state.pageable.pageSize
			};
		},
		set: (newVal: any) => {
			console.log("我是分页更新之后的值", newVal);
		}
	});

	// 初始化的时候需要做的事情就是 设置表单查询默认值 && 获取表格数据(reset函数的作用刚好是这两个功能)
	onMounted(async () => {
		if (initParam.pageIndex && initParam.pageIndex != state.pageable.pageIndex) {
			state.pageable.pageIndex = initParam.pageIndex;
		}
		if (initParam.pageSize && initParam.pageSize != state.pageable.pageSize) {
			state.pageable.pageSizes = [
				initParam.pageSize,
				initParam.pageSize * 2,
				initParam.pageSize * 10,
				initParam.pageSize * 50,
				initParam.pageSize * 100
			];
			state.pageable.pageSize = initParam.pageSize;
		}
		if (!ignoreInit) {
			await getTableList();
			state.defaultExpandKeys = [state.tableData?.[0]?.[selectId]];
		}
	});

	/**
	 * @description 获取表格数据
	 * @return void
	 * */
	const getTableList = async () => {
		if (!api) {
			return;
		}
		try {
			// 先把初始化参数和分页参数放到总参数里面
			Object.assign(state.totalParam, initParam, isPageable ? pageParam.value : {});
			let { result } = await api(state.totalParam);
			dataCallBack && (result = dataCallBack(result));
			// state.tableData = isPageable ? result.datalist : result;
			state.tableData = result.datalist;
			// 解构后台返回的分页数据 (如果有分页更新分页信息)
			const { pageIndex, pageSize, total } = result;
			isPageable && updatePageable({ pageIndex, pageSize, total: total || 0, pageSizes: state.pageable.pageSizes });
		} catch (error) {
			console.log(error);
		}
	};

	/**
	 * @description 更新查询参数
	 * @return void
	 * */
	const updatedTotalParam = () => {
		state.totalParam = {};
		// 处理查询参数，可以给查询参数加自定义前缀操作
		let nowSearchParam: { [key: string]: any } = {};
		// 防止手动清空输入框携带参数（这里可以自定义查询参数前缀）
		for (let key in state.searchParam) {
			// * 某些情况下参数为 false/0 也应该携带参数
			if (state.searchParam[key] || state.searchParam[key] === false || state.searchParam[key] === 0) {
				nowSearchParam[key] = state.searchParam[key];
			}
		}
		Object.assign(state.totalParam, nowSearchParam, isPageable ? pageParam.value : {});
	};

	/**
	 * @description 更新分页信息
	 * @param {Object} resPageable 后台返回的分页数据
	 * @return void
	 * */
	const updatePageable = (resPageable: Table.Pageable) => {
		Object.assign(state.pageable, resPageable);
	};

	/**
	 * @description 表格数据查询
	 * @return void
	 * */
	const search = () => {
		state.pageable.pageIndex = 1;
		updatedTotalParam();
		getTableList();
	};

	/**
	 * @description 表格数据重置
	 * @return void
	 * */
	const reset = () => {
		state.pageable.pageIndex = 1;
		state.searchParam = {};
		// 重置搜索表单的时，如果有默认搜索参数，则重置默认的搜索参数
		Object.keys(state.searchInitParam).forEach(key => {
			state.searchParam[key] = state.searchInitParam[key];
		});
		updatedTotalParam();
		getTableList();
	};

	/**
	 * @description 每页条数改变
	 * @param {Number} val 当前条数
	 * @return void
	 * */
	const handleSizeChange = (val: number) => {
		state.pageable.pageIndex = 1;
		state.pageable.pageSize = val;
		getTableList();
	};

	/**
	 * @description 当前页改变
	 * @param {Number} val 当前页
	 * @return void
	 * */
	const handleCurrentChange = (val: number) => {
		state.pageable.pageIndex = val;
		getTableList();
	};

	return {
		...toRefs(state),
		getPageSize,
		getTableList,
		search,
		reset,
		handleSizeChange,
		handleCurrentChange
	};
};
